<template>
  <div class="search-container">
    <input
      type="text"
      v-model="value"
      @input="handleInput"
      placeholder="输入关键词搜索..."
      :disabled="loading"
    />
    <button @click="handleSearchClick" :disabled="loading">
      {{ loading ? '搜索中...' : '搜索' }}
    </button>

    <div v-if="loading" class="loading">加载中...</div>

    <div class="results">
      <template v-if="results.length > 0">
        <div v-for="item in results" :key="item.id" class="result-item">
          {{ item.name }}
        </div>
      </template>
      <template v-else-if="!loading && value">
        <div>无搜索结果</div>
      </template>
    </div>
  </div>
</template>

<script setup>
import { ref, onUnmounted } from 'vue';

// 防抖函数：延迟 delay 后执行，重复调用则重置计时
const debounce = (fn, delay) => {
  let timer = null;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
  };
};

// 节流函数：单位时间内最多执行一次
const throttle = (fn, interval) => {
  let lastTime = 0;
  return (...args) => {
    const now = Date.now();
    if (now - lastTime >= interval) {
      fn.apply(this, args);
      lastTime = now;
    }
  };
};

// 响应式状态
const value = ref(''); // 输入框值
const loading = ref(false); // 加载状态
const results = ref([]); // 搜索结果
const abortController = ref(null); // 用于取消请求的控制器

// 搜索请求核心逻辑
const fetchSearch = async (keyword) => {
  // 空关键词直接清空结果
  if (!keyword.trim()) {
    results.value = [];
    return;
  }

  // 取消上一次未完成的请求（解决请求冲突）
  if (abortController.value) {
    abortController.value.abort();
  }

  // 创建新的请求控制器
  const controller = new AbortController();
  abortController.value = controller;

  try {
    loading.value = true;
    const response = await fetch(`/api/search?keyword=${encodeURIComponent(keyword)}`, {
      signal: controller.signal, // 关联取消信号
    });

    if (!response.ok) throw new Error('请求失败');
    const data = await response.json();
    results.value = data; // 仅更新最新请求的结果
  } catch (error) {
    // 忽略主动取消的错误
    if (error.name !== 'AbortError') {
      console.error('搜索失败:', error);
    }
  } finally {
    loading.value = false;
  }
};

// 防抖处理输入事件（500ms 延迟）
const handleInputDebounced = debounce((val) => {
  fetchSearch(val);
}, 500);

// 输入框变化时触发防抖搜索
const handleInput = () => {
  handleInputDebounced(value.value);
};

// 节流处理搜索按钮点击（1秒内最多一次）
const handleSearchThrottled = throttle(() => {
  fetchSearch(value.value);
}, 1000);

// 按钮点击事件
const handleSearchClick = () => {
  handleSearchThrottled();
};

// 组件卸载时取消未完成的请求
onUnmounted(() => {
  if (abortController.value) {
    abortController.value.abort();
  }
});
</script>

<style scoped>
.search-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 500px;
  margin: 20px;
}

input, button {
  padding: 8px 12px;
  font-size: 14px;
}

button:disabled {
  opacity: 0.7;
  cursor: not-allowed;
}

.loading {
  color: #666;
  font-size: 14px;
  padding: 8px;
}

.results {
  margin-top: 10px;
  border-top: 1px solid #eee;
  padding-top: 10px;
}

.result-item {
  padding: 4px 0;
}
</style>